package com.hronline;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Rect;
import android.os.Bundle;
import android.text.util.Linkify;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import com.encryption.AESEncrypt;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.parser.LoginParser;

public class LoginActivity extends Activity {
	
	ProgressDialog loadingDialog;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_login);
		
		/* check user already login or not
		 * If already login --> Move to Passcode page
		 * else display page to login
		 *  */
		if(checkAlreadyLogin()) /* moving to passcode page */
		{
			moveToPasscodePage();
		}
		else /* still staying this page to login */
		{
			/* create progress dialog */
			loadingDialog	=	new ProgressDialog(this);
			loadingDialog.setMessage("Loading...Please wait");
			
			/* get the scroll view and set active scroll up and down */
			final ScrollView activityRootView = (ScrollView)findViewById(R.id.scrollView);
			activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(
					new OnGlobalLayoutListener() {
						@Override
						public void onGlobalLayout() {
							scrollTheFrameUpAndDown(activityRootView);
						}
					});
			
			
			/* get control user name and pass */
			final EditText edtUserName	=	(EditText)findViewById(R.id.edtUsername);
			final EditText edtPassword	=	(EditText)findViewById(R.id.edtPass);
			
			edtUserName.clearFocus();
			edtPassword.clearFocus();
			
			edtUserName.setText("hrogandalfjones@gmail.com");
			edtPassword.setText("orangeorange");
			
			/* get the button activate and can't login */
			Button btnActivate	=	(Button)findViewById(R.id.btnActive);
			Button btnCantLogin	=	(Button)findViewById(R.id.btnCanLogin);
			
			/* add selector for button when it clicked by user */
			btnActivate.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					/* validate user name and password first
					 * if ok --> call API to login
					 * else --> show error message
					 * */
					if(validateLogin(edtUserName.getText().toString(), edtPassword.getText().toString()))
					{
						/* showing the loading progress */
						loadingDialog.show();
						
						// call API to login
						getApplicationToken(edtUserName.getText().toString(), edtPassword.getText().toString());
					}
					else
					{
						//show error message
						Constant.showErrorMessage(LoginActivity.this, Constant.EMAIL_PASSWORD_INVALID);
					}
				}
			});
			
			btnCantLogin.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					
					/* open browser to show web instruction for user */
					showCantLoginPage();
				}
			});
		}
	}
	
	/* 
	 * VIEW ANIMATION HANDLER
	 * This section is using to write code handler animation on view 
	 * */
	/* This method is used to handle scroll up and down the frame when user enter text for username and pass */
	private void scrollTheFrameUpAndDown(ScrollView scrollView){
		Rect r = new Rect();
		// r will be populated with the coordinates of your view
		// that area still visible.
		scrollView.getWindowVisibleDisplayFrame(r);

		RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
				RelativeLayout.LayoutParams.MATCH_PARENT);
		
		int heightDiff = scrollView.getRootView()
				.getHeight() - (r.bottom - r.top);
		if (heightDiff > 100) { // if more than 100 pixels, its
								// probably a keyboard...
			p.setMargins(0, -150, 0, 0);
			scrollView.setLayoutParams(p);
		} else {
			p.setMargins(0, 0, 0, 0);
			scrollView.setLayoutParams(p);
		}
	}
	
	/* 
	 * SELECTOR
	 * This section is using to write selector using on this activity 
	 * */
	
	/* this method is used to check user already login this application or not */
	private boolean checkAlreadyLogin(){
		SharedPreferences preferences	=	this.getSharedPreferences(Constant.MY_PREFERENCES, MODE_PRIVATE);
		return preferences.getBoolean(Constant.IS_ALREADY_LOGIN, false);
	}
	
	private void moveToPasscodePage(){
		
		Intent intent	=	new Intent(this, PasscodeActivity.class);
//		intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
		this.startActivity(intent);
		
		finish();
		
	}
	
	/* this method is used to validate the value of username and password */
	private Boolean validateLogin(String username, String password){
		/* check empty value */
		if(username.length() == 0 || password.length() == 0)
		{
			return false;
		}
		
		//check valid format of user name
		if(!isValidEmailFormat(username))
		{
			return false;
		}
		
		/* everything is okay */
		return true;
	}
	
	/* check the format email of user name */
	private Boolean isValidEmailFormat(String email)
	{
		return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches();
	}
	
	/* open the cant login web page on browser */
	private void showCantLoginPage(){
		
		View cantLoginView	=	this.getLayoutInflater().inflate(R.layout.cant_login, null);
		
		TextView txtHelpInvalidUser	=	(TextView)cantLoginView.findViewById(R.id.txtHelpInvalidUser);
		Linkify.addLinks(txtHelpInvalidUser, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS);
		
		TextView txtHelpConnection	=	(TextView)cantLoginView.findViewById(R.id.txtHelpInternetConnection);
		Linkify.addLinks(txtHelpConnection, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS);
		
		AlertDialog.Builder alvBuilder	=	new AlertDialog.Builder(this);
		alvBuilder.setCancelable(true);
		final AlertDialog dialog	=	alvBuilder.create();
		dialog.setView(cantLoginView, 0, 0, 0, 0);
		dialog.show();
		
		ImageButton imbClose	=	(ImageButton)cantLoginView.findViewById(R.id.imbClose);
		imbClose.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				dialog.dismiss();
			}
		});
	}
	
	/* this method is used to encrypt data before send to web service */
	private String encryptedData(String textToEncrypt, String keyToEncrypt)
    {
    	try {
    		String valueAfterEncrypt	=	AESEncrypt.encrypt(textToEncrypt, keyToEncrypt);
    		valueAfterEncrypt = URLEncoder.encode(valueAfterEncrypt, "UTF-8");
    		valueAfterEncrypt = valueAfterEncrypt.replace("%0A", "");
    		return valueAfterEncrypt;
			
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidAlgorithmParameterException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BadPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
    }
	
	/* this method is used to check user is admin or not
	 * if is admin --> deny access to this app
	 * else allows access this app
	 *  */
	private void preventAdmin(String jsonString)
	{
		loadingDialog.dismiss();
		
//		if(Constant.currentUser.isAdmin())
//		{
//			/* display message to prevent admin */
//			Constant.showErrorMessage(this, Constant.PREVENT_ADMIN);
//		}
//		else
//		{
			/* saving login success status for this user */
			SharedPreferences preferences	=	LoginActivity.this.getSharedPreferences(Constant.MY_PREFERENCES, MODE_PRIVATE);
			SharedPreferences.Editor editor	=	preferences.edit();
			editor.putBoolean(Constant.IS_ALREADY_LOGIN, true);
			editor.putString(Constant.USER_INFO, jsonString);
			editor.commit();
			
			moveToPasscodePage();
//		}
	}
	
	/*
	 * CALL API TO LOGIN USER
	 * this section is used to call api to login user
	 * */
	
	/* Showing error connection */
	private void showErrorConnection(){
		loadingDialog.dismiss();
		Constant.showErrorMessage(this, Constant.CANNOT_CONNECT_SERVER);
	}
	
	/* this method is used to call login file */
	@SuppressLint("CommitPrefEdits")
	private void login(String applicationToken, String username, String password){
		String encryptedUsername	=	encryptedData(username, Constant.SECRET_KEY);
		String encryptedPassword	=	encryptedData(password, Constant.SECRET_KEY);
		
		String url	=	String.format("%sTokenIssuer/GetAuthorisationToken?ApplicationToken=%s&UserName=%s&Password=%s", Constant.SERVER_ADDRESS, applicationToken, encryptedUsername, encryptedPassword);
		
		AsyncHttpClient client	=	new AsyncHttpClient();
		client.get(url, new AsyncHttpResponseHandler(){
			@Override /* connect to server success */
			public void onSuccess(String content) {
				// TODO Auto-generated method stub
				super.onSuccess(content);
				
				Constant.currentUser	=	LoginParser.parseUserInfo(content);
				
				if(Constant.currentUser != null)
				{
					preventAdmin(content);
				}
			}
			
			@Override /* connect to server fail */
			public void onFailure(Throwable error, String content) {
				// TODO Auto-generated method stub
				super.onFailure(error, content);
				showErrorConnection();
			}
		});
	}
	
	/* this method is used to get application token */
	private void getApplicationToken(final String username, final String password){
		
		String encryptedAppCode		=	encryptedData(Constant.APP_CODE, Constant.SECRET_KEY);
		String url					=	String.format("%sTokenIssuer/GetApplicationToken?ApplicationCode=%s", Constant.SERVER_ADDRESS, encryptedAppCode);
		
		AsyncHttpClient client		=	new AsyncHttpClient();
		client.get(url, new AsyncHttpResponseHandler(){
			@Override //connect to server success
			public void onSuccess(String content) {
				// TODO Auto-generated method stub
				super.onSuccess(content);
				
				String applicationToken	=	LoginParser.parseApplicationToken(content);
				login(applicationToken, username, password);
	
			}
			
			@Override //connect to server fail
			public void onFailure(Throwable error, String content) {
				// TODO Auto-generated method stub
				super.onFailure(error, content);
				showErrorConnection();
			}
		});
	}
}
